package com.hyzh.latte.vehicle.nezha;

import cn.hutool.core.collection.CollectionUtil;
import com.coffee.concurrent.CoffeeExecutorManager;
import com.coffee.concurrent.CoffeeScheduler;
import com.hyzh.latte.vehicle.dmo.PersonGatherDTO;
import com.hyzh.latte.vehicle.dmo.PersonTrackDTO;
import com.hyzh.latte.vehicle.dmo.PersonTrackMessage;
import com.hyzh.latte.vehicle.dmo.entity.ParkPGEntity;
import com.hyzh.latte.vehicle.service.NezhaRecordService;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author songkui
 * @since 2024/4/9 14:48
 */
@Slf4j
public class NezhaPersonSchedule {
    private AtomicBoolean flag = new AtomicBoolean(false);
    private final CoffeeScheduler mochaScheduler;
    private ExecutorService executorService;
    private ScheduledFuture<?>  scheduledFuture;

    private final NezhaRecordService nezhaRecordService;
    private final String park;
    private final ParkPGEntity parkEntity;

    //key : objectId
    private ConcurrentHashMap<String, PersonTrackDTO> personMap = new ConcurrentHashMap<>();
    private ConcurrentHashMap<String, PersonGatherDTO> gatherMap = new ConcurrentHashMap<>();


    public NezhaPersonSchedule(String park, ParkPGEntity parkEntity, NezhaRecordService nezhaRecordService){
        this.park = park;
        this.parkEntity = parkEntity;
        this.nezhaRecordService = nezhaRecordService;
        mochaScheduler = CoffeeExecutorManager.getInstance().getDefaultScheduler();
        executorService = null == executorService ? CoffeeExecutorManager.getInstance().getDefaultExecutor() : executorService;
    }


    public void putData( List<PersonTrackDTO> dataList){
        for (PersonTrackDTO dto : dataList){
            personMap.put(dto.getOid(), dto);
        }
//        log.info("putData message parkCode {} , add size: {} -->  personMap {}", park, dataList.size(),personMap.size());
    }
    public void putGatherData(List<PersonGatherDTO> dataList){
        for (PersonGatherDTO dto : dataList){
            gatherMap.put(dto.key(), dto);
        }
        log.info("putGatherData message  parkCode {} , add size: {} --> gatherMap {}", park, dataList.size(), gatherMap.size());
    }

    public void start(){
        if(flag.compareAndSet(false, true)){
            log.info("Start Person location parkCode {}", park);
            scheduledFuture = mochaScheduler.scheduleWithFixedDelay(this::doPushMessage, 600L, 1000L, TimeUnit.MILLISECONDS, executorService);
        }
    }


    public void stop(){
        try {
            log.info("Stop Person location parkCode {}", park);
            CoffeeScheduler.cancelScheduled(scheduledFuture);
            flag.getAndSet(false);
        }catch (Exception ignored){
            flag.getAndSet(false);
        }
    }


    public void doPushMessage(){
        List<NezhaClient> set = NezhaPersonManager.getInstance().listClientByPark(park);
        if (CollectionUtil.isNotEmpty(personMap) || CollectionUtil.isNotEmpty(gatherMap)){
            PersonTrackMessage personTrackMessage = new PersonTrackMessage();

            Collection<PersonTrackDTO> personTrackRecord = new ArrayList<>(personMap.size());
            personTrackRecord.addAll(personMap.values());

            if (CollectionUtil.isNotEmpty(gatherMap)){
                Collection<PersonGatherDTO> personGatherRecord = new ArrayList<>(gatherMap.size());
                personGatherRecord.addAll(gatherMap.values());
                personTrackMessage.setGatherAlarm(personGatherRecord);
            }
            personTrackMessage.setPersonList(personTrackRecord);

//TODO            personTrackMessage.setGatherAlarm(GatherUtils.buildGatherDto(personTrackRecord, parkEntity));

            doRepositoryRecord(personTrackMessage, parkEntity);
            if (CollectionUtil.isNotEmpty(set)){
                for (NezhaClient client : set){
                    client.sendPersonTrackMsg(personTrackMessage);
                }
            }
        }

        personMap.clear();
        gatherMap.clear();
    }

    public ParkPGEntity parkPGEntity(){
        return this.parkEntity;
    }

    private void doRepositoryRecord(PersonTrackMessage message, ParkPGEntity parkPGEntity){
        Collection<PersonTrackDTO> personTrackRecord = message.getPersonList();

//        log.info("doRepositoryRecord message parkCode {} , personMap {}， gatherMap {}", park, personTrackRecord.size(), gatherMap.size());
//        MochaExecutorSlow.getInstance().getDefaultExecutor().execute(() -> {
//            LocalDateTime localDateTime = LocalDateTime.now();
//            try {
//                nezhaRecordService.savePersonBatch( park, personTrackRecord.stream().map(d -> {
//                    PersonTrackRecordPGEntity entity = d.buildEntity(this.park, localDateTime);
//                    return entity;
//                }).collect(Collectors.toList()));
//            } catch (Exception e) {
//                log.error("save error", e);
//            }
//        });

    }




}
